home *** CD-ROM | disk | FTP | other *** search
- /*
- * Copyright (C) 1994, Silicon Graphics, Inc.
- * All Rights Reserved.
- *
- * This is UNPUBLISHED PROPRIETARY SOURCE CODE of Silicon Graphics, Inc.;
- * the contents of this file may not be disclosed to third parties, copied or
- * duplicated in any form, in whole or in part, without the prior written
- * permission of Silicon Graphics, Inc.
- *
- * RESTRICTED RIGHTS LEGEND:
- * Use, duplication or disclosure by the Government is subject to restrictions
- * as set forth in subdivision (c)(1)(ii) of the Rights in Technical Data
- * and Computer Software clause at DFARS 252.227-7013, and/or in similar or
- * successor clauses in the FAR, DOD or NASA FAR Supplement. Unpublished -
- * rights reserved under the Copyright Laws of the United States.
- */
-
- /* putmidi.c link with -lmidi -lm -lC */
-
- #include <midi.h>
- #include <miditime.h>
- #include <midiio.h>
- #include <signal.h>
- #include <stdio.h>
- #include <string.h>
- #include <math.h>
- /* for signal handler */
-
- #define MAXEVENTS 1
-
- int verbose = 0;
- int caught_sigint = 0; /* completion flag */
- FILE *infile = stdin;
- MItime timeofday; /* time of day of first event */
-
- static char *types[] = {"MIMESSAGE","MISYSEX","MIREALTIME","MISYSCOM",""};
- static char *messages[] = {
- "Off",
- "On",
- "PolyKeyPressure - ",
- "Damper Pedal at ",
- "All Notes Off at ",
- "Omni Mode Off. next byte:",
- "Omni Mode On. next byte:",
- "Mono Mode On. next byte:",
- "Poly Mode On. next byte:",
- "Modulation Wheel at ",
- "Program Change to #",
- "Channel Pressue - ",
- "Pitch Bender at ",
- ""};
-
- static int status[] = {
- MIDI_NoteOff,
- MIDI_NoteOn,
- MIDI_PolyKeyPressure,
- MIDI_ControlChange,
- MIDI_ChannelModeSelect,
- MIDI_ChannelModeSelect,
- MIDI_ChannelModeSelect,
- MIDI_ChannelModeSelect,
- MIDI_ChannelModeSelect,
- MIDI_ControlChange,
- MIDI_ProgramChange,
- MIDI_ChannelPressure,
- MIDI_PitchBendChange,
- 0x0};
-
- static int byte1[] = {
- 0x0,
- 0x0,
- 0x0,
- MC_DamperPedal,
- MC_AllNotesOff,
- MC_OmniModeOff,
- MC_OmniModeOn,
- MC_MonoModeOn,
- MC_PolyModeOn,
- MC_ModulationWheel,
- 0x0,
- 0x0,
- 0x0,
- 0x0};
-
-
- void catch_sigint()
- {
- caught_sigint=1;
- }
-
- void printMImessage(MImessage mimsg)
- /* Keep in mind this is done with what I could make out from the
- MIDI specification from the klunker Roland Juno-106 */
- {
- printf(" device = %d, channel = %d, length = %d.\n",
- MIdevice(mimsg), MIchannel(mimsg), MIlength(mimsg));
- printf(" status = ");
- switch(MIstatus(mimsg) & MIDI_StatusMask)
- {
- /* case MIDI_ChannelVoice: <-- these are the same */
- case MIDI_NoteOff: /* 0x80 - 1000 0000 */
- {
- printf("Note %x Off - velocity %x\n",
- MIbyte1(mimsg), MIbyte2(mimsg));
- break;
- }
- case MIDI_NoteOn: /* 0x90 - 1001 0000 */
- {
- if(MIbyte2(mimsg) == 0) /* this is equivalent */
- /* to a MIDI_NoteOff */
- {
- printf("Note %x Off - velocity 00\n",
- MIbyte1(mimsg));
- }
- else
- {
- printf("Note %x On - velocity %x\n",
- MIbyte1(mimsg), MIbyte2(mimsg));
- }
- break;
- }
- case MIDI_PolyKeyPressure: /* 0xa0 - 1010 0000 */
- {
- printf("PolyKeyPressure - %x\n",MIbyte2(mimsg));
- break;
- }
- /* case MIDI_ControlChange: <-- these are the same */
- case MIDI_ChannelModeSelect: /* 0xb0 - 1011 0000 */
- {
- switch(MIbyte1(mimsg))
- {
- case MC_DamperPedal: /* 0x40 - 0100 0000 */
- {
- printf("Damper Pedal at %x\n",
- MIbyte2(mimsg));
- }
- case MC_AllNotesOff: /* 0x7b - 0111 1011 */
- {
- printf("All Notes Off at %x\n",
- MIbyte2(mimsg));
- }
- case MC_OmniModeOff: /* 0x7c - 0111 1100 */
- {
- printf("Omni Mode Off. next byte:%x\n",
- MIbyte2(mimsg));
- }
- case MC_OmniModeOn: /* 0x7d - 0111 1101 */
- {
- printf("Omni Mode On. next byte:%x\n",
- MIbyte2(mimsg));
- }
- case MC_MonoModeOn: /* 0x7e - 0111 1110 */
- {
- printf("Mono Mode On. next byte:%x\n",
- MIbyte2(mimsg));
- }
- case MC_PolyModeOn: /* 0x7f - 0111 1111 */
- {
- printf("Poly Mode On. next byte:%x\n",
- MIbyte2(mimsg));
- }
- case MC_ModulationWheel:/* 0x01 - 0000 0001 */
- {
- printf("Modulation Wheel at %x\n",
- MIbyte2(mimsg));
- }
- }
- break;
- }
- case MIDI_ProgramChange: /* 0xc0 - 1100 0000 */
- {
- printf("Program Change to #%x.\n",
- MIbyte1(mimsg));
- break;
- }
- case MIDI_ChannelPressure: /* 0xd0 - 1101 0000 */
- {
- printf("Channel Pressue - %x.\n",MIbyte1(mimsg));
- break;
- }
- case MIDI_PitchBendChange: /* 0xe0 - 1110 0000 */
- {
- printf("Pitch Bender at %x.\n",
- 128 * MIbyte2(mimsg) + MIbyte1(mimsg));
- break;
- }
- }
- }
-
-
- void printevents(MIevent *mievent, int num_events)
- {
- /*
- Remember: within the MIevent structure is the timestamp and the message
- buffer. within the message buffer lies the MImessage structure and the buffer for system exclusive dats.
- */
-
- MItime mitime;
- MImessage mimsg;
- unsigned char *misysexbuf;
- int i,j;
- static long eventnum = 0;
-
- if(!eventnum) /* first event get time of day */
- {
- printf(" STARTING time %d:%d:%f.\n",
- MItimegethours(&timeofday),
- MItimegetminutes(&timeofday),
- (float)MItimegetsecs(&timeofday) +
- ((float)MItimegetmicros(&timeofday) / 1000000.0));
- eventnum++;
- }
-
- for (i=0; i < num_events; i++)
- {
- printf("EVENT #%d - ",eventnum++);
- /*
- mitime = MItimesubtract(&mievent[i].dt,&timeofday);
- */
- MItimecopy(&mitime,&mievent[i].dt);
- mimsg = mievent[i].mm.msgbuf;
- misysexbuf = mievent[i].mm.sysexbuf;
- switch(mievent[i].t)
- {
- case MIMESSAGE:
- {
- printf("MIMESSAGE ( = %x)\n",mimsg);
- printMImessage(mimsg);
- break;
- }
- case MISYSEX:
- {
- printf("MISYSEX\n");
-
- printf("%d bytes: ",mievent[i].count);
- for(j=0; (j<mievent[i].count-1)&&(j<8); j++)
- printf("%x, ",misysexbuf[j]);
- printf("%x %s\n",misysexbuf[j],
- ( (mievent[i].count > 8) ? "..." : ""));
- break;
- }
- case MIREALTIME:
- {
- printf("MIREALTIME\n");
- break;
- }
- case MISYSCOM:
- {
- printf("MISYSCOM\n");
- break;
- }
- default:
- {
- printf("unknown\n");
- break;
- }
- }
-
- printf(" at time %lf.\n", MItimedouble(&mitime)/1000000.0);
- }
- }
-
-
-
- int getevents(MIevent *mievent, int num_events)
- {
- char inline[80];
- char *shaker;
- int i,num,val;
- int channel,device;
- double secs;
- MItime mitime;
- MItime mitime2;
- static int firsttime = 1;
-
- if(firsttime)
- {
- firsttime = !firsttime;
- fgets(inline,80,infile);
- timeofday = MItimecurrentsystemtime(&timeofday);
- }
-
- for(num=0;num<num_events;num++)
- {
- shaker = NULL;
- while((!feof(infile)) && !shaker)
- {
- fgets(inline,80,infile);
- shaker = strstr(inline,"EVENT");
- }
-
- if (feof(infile)) return(-1-num);
-
- for(i=0; (types[i][0]) && !strstr(shaker,types[i]); i++);
- if(!types[i][0])
- {
- printf("unknown message type %s\n",shaker);
- num--;
- }
- else
- {
- mievent[num].t = i;
-
- if (feof(infile)) return(-1-num);
- fgets(inline,80,infile);
-
- if (!(shaker = strstr(inline,"channel = ")))
- {
- printf("no channel found.\n");
- num--;
- }
- else
- {
- sscanf(shaker+strlen("channel = "),"%d",&channel);
- MImakemessage(&mievent[num].mm.msgbuf,0x80,0x0,0x0,0x0);
- MIsetchannel(&mievent[num].mm.msgbuf, channel);
- /* error in define for MIsetchannel ... was
- #define MIsetchannel(m, c) (__mp(m) &= 0xfff0ffff, __mp(m) |= ((c & 0xf) << 16),MIsetdevice(__mp(m) >> 4))
- */
-
- shaker = strstr(inline,"device = ");
- sscanf(shaker+strlen("device = "),"%d",&device);
-
- if (feof(infile)) return(-1-num);
- fgets(inline,80,infile);
-
- if (!(shaker = strstr(inline,"status = ")))
- {
- printf("no status found.\n");
- num--;
- }
- else
- {
- for(i=0; (messages[i][0]) &&
- !strstr(shaker,messages[i]); i++);
- if(!messages[i][0])
- {
- printf("unknown status type %s\n",shaker);
- num--;
- }
- else
- {
- MIsetstatus(&mievent[num].mm.msgbuf, status[i] >> 4);
- if(status[i] !=
- (MIstatus(mievent[num].mm.msgbuf) & MIDI_StatusMask))
- {
- printf("oops! Status = %x\n",
- MIstatus(mievent[num].mm.msgbuf));
- }
-
- MIsetbyte1(&mievent[num].mm.msgbuf, byte1[i]);
- if((status[i] == MIDI_NoteOn) ||
- (status[i] == MIDI_NoteOff))
- {
- shaker = strstr(inline,"Note ");
- sscanf(shaker+strlen("Note "),"%x", &val);
- MIsetbyte1( &mievent[num].mm.msgbuf, val);
-
- shaker = strstr(inline,"velocity ");
- sscanf(shaker+strlen("velocity "), "%x",&val);
- MIsetbyte2( &mievent[num].mm.msgbuf, val);
- }
- else
- {
- sscanf(shaker+strlen(messages[i]), "%x",&val);
- if (status[i] == MIDI_PitchBendChange)
- {
- MIsetbyte1( &mievent[num].mm.msgbuf, val%128);
- MIsetbyte2( &mievent[num].mm.msgbuf, val/128);
- }
- else if((status[i]==MIDI_ChannelPressure)||
- (status[i]==MIDI_ProgramChange)||
- (status[i]==MIDI_PolyKeyPressure))
- {
- MIsetbyte1( &mievent[num].mm.msgbuf, val);
- }
- else
- {
- MIsetbyte2( &mievent[num].mm.msgbuf, val);
- }
- }
-
- if (feof(infile)) return(-1-num);
- fgets(inline,80,infile);
-
- if (!(shaker = strstr(inline," at time ")))
- {
- printf("no time found.\n");
- num--;
- }
- else
- {
- sscanf(shaker+strlen(" at time "), "%lf",
- &secs);
-
- if(verbose)
- printf("read time %lf (%lf %lf)\n",secs,
- floor(secs),
- fmod(secs*1000000.0,1000000.0));
- mitime = MItimecreatesecs((long)floor(secs),
- (long)fmod(secs*1000000.0,1000000.0));
- MItimecopy(&mievent[num].dt,&mitime);
- }
- }
- }
- }
- }
- }
- return num;
- }
-
-
- main(int argc, char **argv)
- {
- MIconfig *miconfig = MInewconfig();
- MIevent mievent[MAXEVENTS];
- MIport *miPort = MInewport();
- extern char *optarg;
- char *infilename;
- int num;
- int c;
- int errflag = 0;
- static unsigned int pbuf[] = {
- MI_STAMPING, MIRELSTAMP,
- MI_BLOCKING, MINONBLOCKING,
- MI_TIMEOUT, 0, 0,
- MI_OUTPUTTIME, 2, 0
- };
- /* config stuff */
- while ((c = getopt(argc, argv, "vf:")) != EOF)
- switch (c) {
- case 'v':
- verbose++;
- break;
- case 'f':
- infilename = optarg;
- break;
- case '?':
- errflag++;
- }
- if(errflag)
- {
- printf("usage: %s [-v] -f <infile>\n",argv[0]);
- exit(1);
- }
-
- sigset(SIGINT,catch_sigint);
- MIsetparams(miconfig,pbuf, 10);
-
- if (MIopen(miPort,"w", miconfig) == -1) /* open midi port */
- {
- if(verbose)
- printf("MIopen: Couldn't open midi port for writing\n");
- exit(1);
- }
- if(verbose)
- {
- printf("MIopen succeded.\n");
-
- printf("MIgetfd: file descriptor is %x\n.", MIgetfd(miPort));
- }
-
- MIsetstart(miPort,NULL);
- timeofday = MItimecurrentsystemtime(&timeofday);
-
- infile = fopen(infilename,"r");
- while(!caught_sigint)
- {
- num = getevents(mievent,MAXEVENTS);
- if (num == 0)
- {
- if(verbose)
- printf("error reading event\n");
- }
- else if (num < 0)
- {
- if(verbose)
- {
- printf("end of file\n");
- printevents(mievent,-num-1);
- }
- num = MIsend(miPort,mievent,-num-1);
- caught_sigint = 1;
- }
- else
- {
- if(verbose)
- printevents(mievent,MAXEVENTS);
- num = MIsend(miPort,mievent,MAXEVENTS);
- if(num == -1)
- {
- if(verbose)
- printf("Error in MIsend.\n");
- exit(1);
- }
- }
- }
-
- sleep(3);
- MIclose(miPort); /* close midi port */
-
- free(miPort);
- free(miconfig);
- }
-